import _clonedeep from 'lodash/cloneDeep'
import varType from '@/utils/varType'
import apiRequest from '@/utils/apiRequest'
import Log from '@/utils/Log'
import math from '@/utils/math'
import numSplit from '@/utils/numSplit'
import { getOptions, fmtClcd } from '@/utils/dictionary'
import CONST from '@/const/const'
import HEY_VALIDATOR from '@/const/hey-validator'
import {mapGetters} from "vuex";

export default {
  data() {
    return {
      CONST,
      HEY_VALIDATOR
    }
  },
  computed: {
    ...mapGetters([
      'permissionList',
      'authorityList'
    ])
  },
  created() {
  },
  mounted() {
  },
  methods: {
    //按钮权限
    hasPermission(permissionCode,row) {
      const permissionList = this.permissionList
      if(!permissionCode){
        return false
      }
      if(permissionList.includes(permissionCode)){
        return true
      }else{
        return false
      }
    },
    //业务权限
    hasAuthority(authorityId,row) {
      const authorityList = this.authorityList
      if(!authorityList){
        return false
      }
      if(authorityList.includes(authorityId)){
        return true
      }else{
        return false
      }
    },

    /*
    数组1是否在数组2之内
     */
    isInArr(arr1, arr2) {
      const len1 = arr1.length
      const len2 = arr2.length
      return len1 <= len2 && arr1.filter(item => arr2.includes(item)).length === len1
    },
    /**
     是否参数是否为空
     var obj = null
     isNull(obj) // true
     @param {Object} obj
     return {Boolean} true/false 为空返回true
     * */
    isNull(obj) {
      return typeof (obj) !== 'number' && (!obj || (Array.isArray(obj) && !obj.length))
    },
    /**
     校验选中数据个数
     @param {Object} data
     @param {String} type '0'不控 '1'单选; '2'一条以上
     * */
    isSelected(data, type = '0') {
      if (type === '0') {
        return true
      }
      if (this.isNull(data)) {
        this.$message.warning('请选中一条数据')
        return false
      }
      const len = data.length
      if (type === '1' && len !== 1) { // 必选且单选，eg:修改
        this.$message.warning('仅支持单选操作')
        return false
      } else if (type === '2' && !len) { // 必选且单选或多选
        this.$message.warning('请选择至少一条数据后操作')
        return false
      }
      return true
    },
    cloneDeep(obj, deep = true) {
      return _clonedeep(obj, deep)
    },
    math(num1, num2, oper, percision) {
      return math(num1, num2, oper, percision)
    },
    fmoney(s, num = 3, decimal, non = ',') {
      return numSplit(s, non, num, decimal)
    },
    /**
     * 获取clcd码值 {0: '否'}
     * @param {String} clcd
     * @returns {*}
     */
    getOptions(type) {
      return getOptions.call(this, type)
    },
    /**
     * 格式化码值 1 -> 是
     * @param {String} clcd
     * @param {String} value
     * @returns {*}
     */
    fmtClcd(type, value) {
      return fmtClcd.call(this, type, value)
    },
    varType,
    /**
     * 弹出提示
     * @param  {String} msg *提示信息
     * @param  {Function} fn 点击确定后续操作
     */
    $info(msg, fn = () => {}) {
      Log.info.call(this, msg, fn)
    },
    /**
     * 弹出警告
     * @param {String} msg 提示信息
     * @param  {Function} fn 点击确定后续操作
     */
    $warn(msg, fn = () => {}) {
      Log.warn.call(this, msg, fn)
    },
    /**
     * 弹出错误
     * @param {String} msg 提示信息
     * @param  {Function} fn 点击确定后续操作
     */
    $error(msg, fn = () => {}) {
      Log.error.call(this, msg, fn)
    },
    /**
     * 弹出确认提示
     * @param {String} msg 提示信息
     * @param {Function} fn 确认回调
     * @param {Function} clFn 取消回调
     */
    $sure(msg, fn = () => {}, clFn = () => {}) {
      Log.sure.call(this, msg, fn, clFn)
    },
    /**
     * 根据目标对象的键去赋值
     const source = {name: '1'}
     const target = {name: ''}
     this.assignData(source, target)
     console.log('target', target)
     * @param source 源对象
     * @param target 目标对象
     * return {Object} 返回目标对象
     *
     */
    assignData(source = {}, target = {}) {
      Object.keys(target).forEach(key => {
        if (source.hasOwnProperty(key)) {
          const sourceValue = source[key]
          const type = this.varType(sourceValue)
          if (type === 'number') {
            target[key] = sourceValue === null ? null : sourceValue
          } else if (type === 'array') {
            target[key].splice(0, target[key].length, ...sourceValue)
          } else if (type === 'object') {
            this.assignData(sourceValue, target[key])
          } else {
            target[key] = sourceValue || null
          }
        }
      })
      return target
    },
    /**
     * 重置对象
     * resetObj({name: '1'}) // {name: ''}
     * @param obj
     */
    resetObj(obj) {
      Object.keys(obj).forEach(key => {
        this.resetValue(obj, key)
      })
    },
    /**
     * 重置对象里某个key
     * resetValue({name: '1'}, 'name') // {name: ''}
     * @param obj
     * @param key
     */
    resetValue(obj, key) {
      const type = varType(obj[key])
      const _obj = obj[key]
      if (type === 'string') {
        obj[key] = ''
      } else if (type === 'object') {
        this.resetObj(_obj)
      } else if (type === 'array') {
        _obj.splice(0, _obj.length, _obj[0])
        this.resetValue(_obj, 0)
      } else {
        obj[key] = null
      }
    },
    addPageParam(param = {}, pageNum = 1, pageSize = 10) {
      Object.assign(param, {
        pageSize,
        pageNum
      })
    },
    post(url, param, opts = { showLoading: true}) {
      return apiRequest.post(url, param, opts)
    },
    postUseBlob(url, param, opts = { showLoading: true}) {
      return apiRequest.postUseBlob(url, param, opts)
    },
    get(url, param, opts = { showLoading: true }) {
      return apiRequest.get(url, param, opts)
    },
    /**
     * 发送分页请求
     * const ret = await post('AL0441602', {"rcrd_id": "1", "mnplt_tpcd": "2"})
     * @param {String} transId *交易号
     * @param {Object} param 请求内容
     * @param {Object} opts
     * @return Promise
     */
    postPage(transId, param = {}, pageNum = 1, pageSize = 10, opts = { showLoading: true }) {
      this.addPageParam(param, pageSize, pageNum)
      return new Promise((resolve, reject) => {
        this.post(transId, param, opts).then(ret => {
          const grpData = ret.data
          if (!grpData) {
            for (const [key] of Object.entries(ret)) {
              if (key.includes('grp')) {
                ret.data = ret[key]
                break
              }
            }
          }
          resolve(ret)
        }).catch(err => {
          reject(err)
        })
      })
    },
    getPage(transId, param = {}, pageNum = 1, pageSize = 10, opts = { showLoading: true }) {
      this.addPageParam(param, pageSize, pageNum)
      return new Promise((resolve, reject) => {
        this.get(transId, param, opts).then(ret => {
          this.resolvePage(ret, resolve)
        }).catch(err => {
          reject(err)
        })
      })
    },
    resolvePage(ret, resolve) {
      const grpData = ret.data
      if (!grpData) {
        for (const [key] of Object.entries(ret)) {
          if (key.includes('grp')) {
            ret.data = ret[key]
            break
          }
        }
      }
      resolve(ret)
    }
  }
}
